<template>
	<el-table :data="tbData" default-expand-all :border="true" ref="table" :fit="true">
		<el-table-column label="键" width="150">
			<template slot-scope="scope">
				<el-input v-model="scope.row.key" :maxlength="20" @input="dataChange(scope.$index,'key',scope.row)">
				</el-input>
			</template>
		</el-table-column>
		<el-table-column label="类型" width="120">
			<template slot-scope="scope">
				<el-select v-model="scope.row.type" @change="dataChange(scope.$index,'type',scope.row)">
					<el-option v-for="(item,index) in typeOptions" :key="index" :label="item" :value="item">
					</el-option>
				</el-select>
			</template>
		</el-table-column>
		<el-table-column label="描述" min-width="150" class="closeSpan">
			<template slot-scope="scope">
				<el-input type="textarea" resize="vertical" :autosize="{ minRows: 1}" v-model="scope.row.describe"
					@input="dataChange(scope.$index,'describe',scope.row)">
				</el-input>
				<i class="el-icon-close close" @click="removeData(scope.row.key,scope.$index)"></i>
			</template>
		</el-table-column>
	</el-table>

</template>

<script>
	export default {
		name: '',
		components: {

		},
		props: {
			req: {
				type: Object
			}
		},
		model: ['req'],
		data() {
			return {
				typeOptions: ['Int', 'Float', 'Boolean', 'String', 'Char', 'Array', 'Object'],
				lastData: [],
				defaultData: {
					key: '',
					type: '',
					describe: ''
				}
			}
		},
		computed: {
			tbData() {
				let keys = Object.keys(this.req.data)
				this.synchDescribe(this.lastData, keys)
				this.lastData = keys
				let data = []
				for (let key of keys) {
					data.push({
						key: key,
						type: this.type(key),
						describe: this.describe(key)
					})
				}


				data.push(JSON.parse(JSON.stringify(this.defaultData)))
				return data
			},
			type() {
				return function(key) {
					let val = this.req.data[key]
					if (Array.isArray(val)) return 'Array'
					else if (typeof(val) == 'object') return 'Object'
					else if (typeof(val) == 'string') return 'String'
					else if (typeof(val) == 'boolean') return 'Boolean'
					else if (parseInt(val) == val) return 'Int'
					else if (typeof(val) == 'number') return 'Float'
				}
			},
			describe() {
				return function(key) {
					if (this.req.describe[key] != undefined) return this.req.describe[key]
					this.req.describe[key] = ''
					return ''
				}

			}
		},
		methods: {
			findDifferent(old, val) {
				let o = new Set(old)
				let v = new Set(val)
				let last = new Set([...o].filter(x => !v.has(x)))
				let news = new Set([...v].filter(x => !o.has(x)))
				return [
					[...last][0],
					[...news][0]
				]
			},
			synchDescribe(old, val) {
				if (old.length == val.length) {
					let res = this.findDifferent(old, val)
					let last = res[0],
						news = res[1]
					if (last != news) {
						this.$set(this.req.describe, news, this.req.describe[last])
						this.$delete(this.req.describe, last)
					}
				}
			},
			addData() {
				this.tbData.push(JSON.parse(JSON.stringify(this.defaultData)))
			},
			dataChange(index, key, scope) {
				if (index == this.tbData.length - 1) this.addData()

				let data = this.req.data
				let describe = this.req.describe
				if (key == 'key') {

					let keys = Object.keys(data)
					let oKey = keys[index]
					let val = data[oKey] || ''
					this.$set(data, scope[key], val)
					this.$delete(data, oKey)

					val = describe[oKey] || ''
					this.$set(describe, scope[key], val)
					setTimeout(() => {
						this.$delete(describe, oKey)
					}, 10)
				} else if (key == 'type') {

				} else if (key == 'describe') {
					this.$set(describe, scope['key'], scope['describe'])
				}
			},
			removeData(key, index) {
				if (index == this.tbData.length - 1) return
				this.$delete(this.tbData, index)
				this.$delete(this.req.data, key)
				this.$delete(this.req.describe, key)
			}
		},
		watch: {

		},
		created() {

		}
	}
</script>

<style scoped="">
	.close {
		font-size: 18px;
		margin: 3px;
		opacity: 0.3;
		color: #9f9f9f;
		transition: all 0.3s;
	}

	.close:hover {
		opacity: 1;
		color: #f3f3f3;
		transition: all 0.3s;
		border-radius: 10px;
		background-color: #a7a7a7;
	}
</style>
